package cn.nexd.app.guestsystem.presenter;

import android.app.Activity;
import android.content.Context;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import cn.nexd.app.guestsystem.Configuration;
import cn.nexd.app.guestsystem.R;
import cn.nexd.app.guestsystem.database.DatabaseUtil;
import cn.nexd.app.guestsystem.model.User;
import cn.nexd.app.guestsystem.ui.inter.IMainView;
import cn.nexd.framework.error.NexdCrashException;
import cn.nexd.framework.util.FileUtil;
import cn.nexd.framework.util.Logger;
import cn.nexd.sdk.collector.NexdCollector;
import cn.nexd.sdk.collector.NexdCollectorAgent;
import cn.nexd.sdk.collector.NexdCollectorConfiguration;
import cn.nexd.sdk.collector.NexdCollectorResult;
import cn.nexd.sdk.collector.NexdCollectorResultListener;

/**
 * Created by wangxu on 16/8/30.
 */
public class MainPresenter extends BasePresenter<IMainView> {

    private static final String TAG = "MainPresenter";
    private static Map<String, User> userMap; // 内存中存储白名单的集合
    private final List<User> waitShow; // 待显示队列
    private List<User> alreadyShow; // 备用显示队列
    private List<User> blackList;
    private ScheduledThreadPoolExecutor executor; // timer线程
    NexdCollectorAgent collectorAgent;


    public MainPresenter(Context context, IMainView iView) {
        super(context, iView);
        userMap = new HashMap<>();
        waitShow = new ArrayList<>();
        alreadyShow = new ArrayList<>();
        blackList = new ArrayList<>();
        executor = new ScheduledThreadPoolExecutor(1);
    }

    /**
     * 初始化白名单,将白名单数据存储在内存中
     */
    public void initWhiteList() {
        String configPath = Configuration.getPath(Configuration.Path.NAMES_PATH);
        try {
            if (!FileUtil.checkExist(configPath)) {
                iView.showToast(context.getString(R.string.error_names_file));
            } else {
                String whiteString = FileUtil.readFile(configPath);
                parseJson(whiteString);
            }
        } catch (IOException e) {
            e.printStackTrace();
            NexdCrashException.getInstance().reportException(e);
        }
    }

    private void parseJson(String json) {
        try {
            JSONObject jsonObject = new JSONObject(json);
            Configuration.Config.Greet = jsonObject.getString("greet");
            JSONArray whiteArray = jsonObject.getJSONArray("configs");
            for (int i = 0; i < whiteArray.length(); i++) {
                JSONObject whiteJson = whiteArray.getJSONObject(i);
                userMap.put(whiteJson.getString("uuid"),
                        new User(
                                whiteJson.getString("uuid"),
                                whiteJson.getString("mac"),
                                whiteJson.getString("company"),
                                whiteJson.getString("position"),
                                whiteJson.getString("familyName"),
                                whiteJson.getString("name"),
                                whiteJson.getString("weight")));
            }
            Logger.info(TAG, "配置文件读取成功    " + whiteArray.toString());
        } catch (JSONException e) {
            e.printStackTrace();
            NexdCrashException.getInstance().reportException(e);
        }
    }

    private void startCollector() {
//        if (collectorAgent != null) {
//            collectorAgent.stopCollector();
//        }
//        // 定时开启和关闭蓝牙.
//

        NexdCollectorConfiguration.Builder builder = new NexdCollectorConfiguration.Builder();
        builder.setAppkey("")
                .setBeaconCollectorDelay(1000)
                .setBeaconCollectorRate(1000)
                .setBeaconResultCacheTime(2000)
                .setCollectorRate(500)
                .setCollectorDelay(500)
                .setBeaconCollectorEnable(true)
                .setDebugMode(true)
                .setWifiCollectorEnable(false)
                .setBeaconScanMode(NexdCollectorConfiguration.CollectorScanMode.SCAN_MODE_BALANCED);

        // 开始采集,  采集中的临时集合尽量不要提取处理啊,有可能会影响业务
        collectorAgent.startCollector(builder.build(), new NexdCollectorResultListener() {
            @Override
            public void onCollectorChanged(NexdCollector nexdCollector, List<NexdCollectorResult> list) {
                if (list != null) {
                    for (NexdCollectorResult nexdCollectorResult : list) {
                        // 将白名单的 Beacon 过滤出来, 并且从 wait 和 already 两个队列中排除,将新采集到的信号
                        // 添加到等待队列中,等待显示.
                        if (nexdCollectorResult == null) continue;
                        final String uuid = nexdCollectorResult.getSingleSourceUuid() + nexdCollectorResult.getSingleSourceMajor() + nexdCollectorResult.getSingleSourceMinor();
                        if (userMap.containsKey(uuid)) {
                            User user = userMap.get(uuid);
                            if (!waitShow.contains(user) && !alreadyShow.contains(user)) {

                                if (blackList.contains(user)) {
                                    if (System.currentTimeMillis() - user.getExitTimeMill() > 20000) {
                                        blackList.remove(user);
                                    }
                                } else {
                                    synchronized (waitShow) {
                                        Logger.info(TAG, user.toString());
                                        waitShow.add(user);
                                    }
                                }

                            }
                        }
                    }
                    // 纯纯, 你猜我在这里做了什么
                    DatabaseUtil.insertAllMac(list);
                }
            }
        });

    }

    /**
     * 初始化采集业务,将采集到的结果装填到待显示队列中,并将采集到的结果无差别的存储在数据库中
     */
    public void initCollect() {
        // 初始化采集业务
        collectorAgent = NexdCollectorAgent.getCollectorAgent(context);
        // 自动定时器,定时发送待现实的数据
        startCollector();
        startNotifyForward();
    }

    /**
     * 定时向前台发送显示内容
     */
    private void startNotifyForward() {
        executor.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // wait 队列的优先级比 already 队列的优先级高
                        if (waitShow.size() > 0) {
                            // 第一次显示,默认计数 1次,但不修改自增器.
                            // 当显示完成后,将此数据添加到 already 队列的尾巴,并将此数据从 wait 队列移除
                            iView.setShowText(waitShow.get(0));
                            synchronized (waitShow) {
                                alreadyShow.add(waitShow.get(0));
                                waitShow.remove(0);
                            }
                        } else if (alreadyShow.size() > 0) {
                            // 总计显示3次, wait 时,显示一次, already 里显示2次.
                            // 每次显示时, 优先显示, 当判断出当前被显示了3次时, 不会再将数据追加到队列的尾巴,
                            // 从而实现移除队列的操作,并且将对象的计数器重新设置为 0, 方便下一次被扫描
                            User user = alreadyShow.get(0);
                            iView.setShowText(user);
                            user.incrementCount(); // 自增计数器
                            alreadyShow.remove(0);
                            if (user.getCount() < 2) {
                                alreadyShow.add(user);
                            } else {
                                user.setExitTimeMill(System.currentTimeMillis());
                                blackList.add(user);
                                user.resetCount();
                            }
                        } else {
                            // 当所有队列都轮空时,认为没有来宾没扫描到,此时应显示 "欢迎各位来宾", 由前台控制显示内容
                            iView.setShowText(null);
                        }
                    }
                });
            }
        }, 1000, 3000, TimeUnit.MILLISECONDS);
    }

    /**
     * 从数据库中导出所有 Mac 地址, 地址去重复后写成文件,存储在 SDCard 中.
     */
    public void getAllMac() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //  纯纯, 你猜我干了啥
                List<String> macAddress = DatabaseUtil.getAllMacAddress();
                String saveMacPath = Configuration.getPath(Configuration.Path.REPORT_PATH);
                StringBuilder builder = new StringBuilder();
                try {
                    if (FileUtil.checkExist(saveMacPath)) {
                        FileUtil.deleteFile(saveMacPath);
                    }
                    for (String macAddres : macAddress) {
                        builder.append(macAddres)
                                .append("\n");
                    }
                    FileUtil.writeFile(saveMacPath, builder.toString());
                    ((Activity) context).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            iView.showToast(context.getString(R.string.success_database_report));
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                    NexdCrashException.getInstance().reportException(e);
                }
            }
        }).start();
    }

}
